import polars as pl
import re
from pathlib import Path
import fastexcel

from constant import Constant


class Config:
    def __init__(self, file_path: str):
        self.file_path = file_path
        self.base_config, self.data_config_groups = self.__parse_excel_config(file_path)

    def __parse_excel_config(self, file_path: str) -> tuple[dict, dict[str, list[dict]]]:
        """
        解析 Excel 配置文件，返回基础配置和按 sheet 分组的数据配置
        
        参数:
            file_path: Excel 文件路径
        
        返回:
            元组，包含基础配置字典和按 sheet 分组的数据配置字典
        """
        # 检查文件是否存在
        if not Path(file_path).exists():
            raise FileNotFoundError(f"文件不存在: {file_path}")

        # 获取所有表名
        try:
            # 使用 fastexcel 引擎获取所有表名
            sheet_names = fastexcel.read_excel(file_path).sheet_names
        except Exception as e:
            raise Exception(f"无法读取 Excel 文件: {e}")

        # 解析基础配置
        base_config = {}
        for sheet_name in sheet_names:
            if sheet_name.startswith('@'):
                try:
                    # 读取指定工作表
                    df = pl.read_excel(file_path,
                                    sheet_name=sheet_name,
                                    infer_schema_length=0)

                    # 检查是否包含必要的列
                    required_columns = ['配置项', '实际替换值']
                    if not all(col in df.columns for col in required_columns):
                        print(
                            f"警告: 基础配置表 '{sheet_name}' 缺少必要的列: {required_columns}")
                        continue
                    
                    # 转换为字典
                    for row in df.rows(named=True):
                        key = row['配置项']
                        value = row['实际替换值'] 
                        if key:
                            base_config[key] = value
                except Exception as e:
                    print(f"警告: 解析基础配置表 '{sheet_name}' 时出错: {e}")

        # 解析数据配置，按 sheet 分组
        data_config_groups = {}
        for sheet_name in sheet_names:
            if not sheet_name.startswith('@') and not sheet_name.startswith('#'):
                data_configs = []
                try:
                    # 读取指定工作表
                    df = pl.read_excel(file_path,
                                    sheet_name=sheet_name,
                                    infer_schema_length=0)

                    # 检查是否包含必要的列
                    required_columns = ['序号', '项目名', '最后修改人', '目标表']
                    if not all(col in df.columns for col in required_columns):
                        print(
                            f"警告: 数据配置表 '{sheet_name}' 缺少必要的列: {required_columns}")
                        continue

                    # 处理每一行数据
                    for row in df.rows(named=True):
                        # 跳过序号为空的行
                        if not row.get('序号'):
                            continue

                        # 验证必填字段
                        required_values = {
                            '项目名': row.get('项目名'),
                            '最后修改人': row.get('最后修改人'),
                            '目标表': row.get('目标表')
                        }
                        missing_fields = [
                            field for field, value in required_values.items()
                            if not value
                        ]
                        if missing_fields:
                            print(
                                f"警告: 表 '{sheet_name}' 行 {row.get('序号')} 缺少必填字段: {', '.join(missing_fields)}"
                            )
                            continue

                        # 处理数据源，为空时使用目标表
                        source_table = row.get('数据源') or row['目标表']

                        # 处理转码字段，分割为列表
                        transcode_fields = row.get('转码字段', '').split(',') if row.get('转码字段', '') else []
                        transcode_fields = [
                            field.strip() for field in transcode_fields
                            if field.strip()
                        ]

                        # 处理数据库链，替换占位符
                        data_chain = row.get('数据库链', '')
                        if data_chain:
                            # 查找所有 {key} 格式的占位符
                            placeholders = re.findall(r'\{([^}]+)\}', data_chain)
                            for placeholder in placeholders:
                                if placeholder in base_config:
                                    data_chain = data_chain.replace(
                                        f"{{{placeholder}}}",
                                        base_config[placeholder])
                                else:
                                    print(
                                        f"警告: 数据库链 '{data_chain}' 中的占位符 '{{{placeholder}}}' 在基础配置中未找到"
                                    )

                        # 处理同步策略
                        sync_strategy = row.get('同步策略').lower() if row.get('同步策略') else '替换'
                        if sync_strategy not in ['', '替换', '合并', '删除']:
                            print(
                                f"警告: 表 '{sheet_name}' 行 {row.get('序号')} 的同步策略值 '{sync_strategy}' 无效"
                            )

                        # 处理同步开关
                        sync_switch = row.get('同步开关').lower() if row.get('同步开关') else '开启'
                        if sync_switch not in ['', '开启', '关闭']:
                            print(
                                f"警告: 表 '{sheet_name}' 行 {row.get('序号')} 的同步开关值 '{sync_switch}' 无效"
                            )

                        # 处理系统状态
                        system_status = row.get('系统状态')
                        if system_status is not None and str(system_status).strip(
                        ) not in ['', '10', '70', '90']:
                            print(
                                f"警告: 表 '{sheet_name}' 行 {row.get('序号')} 的系统状态值 '{system_status}' 无效"
                            )

                        # 构建数据配置项
                        config = {
                            '序号': row.get('序号'),
                            '项目名': row.get('项目名'),
                            '最后修改人': row.get('最后修改人'),
                            '目标表': row.get('目标表'),
                            '目标表筛选条件': row.get('目标表筛选条件', ''),
                            '数据源': source_table,
                            '数据源筛选条件': row.get('数据源筛选条件', ''),
                            '转码字段': transcode_fields,
                            '自定义同步规则': row.get('自定义同步规则', ''),
                            '同步策略': sync_strategy,
                            '数据库链': data_chain,
                            '同步开关': sync_switch,
                            '系统状态': system_status,
                            '备注说明': row.get('备注说明', '')
                        }

                        data_configs.append(config)

                    # 按序号排序
                    data_configs.sort(key=lambda x: x['序号'])

                    # 添加到分组
                    if data_configs:  # 只添加有数据的分组
                        data_config_groups[sheet_name] = data_configs
                except Exception as e:
                    print(f"警告: 解析数据配置表 '{sheet_name}' 时出错: {e}")

        return base_config, data_config_groups
    
    def is_multi_line(self, s):
        """
        检查字符串中是否包含换行符
        :param s: 输入的字符串
        :return: 若包含换行符返回 True，否则返回 False
        """
        return s.find('\n') != -1 or s.find('\r') != -1 or s.find('\r\n') != -1




if __name__ == "__main__":
    # 示例用法
    file_path = "config.xlsx"

    conf = Config(file_path)
    print(conf)
    print(conf.base_config)

    for sheet_name, configs in conf.data_config_groups.items():
        print("==========================")
        print(sheet_name)
        for config in configs:
            field_index = 0
            for key, value in config.items():
                if key == Constant.SEQ_NO:
                    continue
                prefix = f"{4*' '}- " if field_index == 0 else f"{6*' '}"
                if isinstance(value, str) and conf.is_multi_line(value):
                    print(f"{prefix}{Constant.chs2enkey(key)}: 多行字符串")
                else:
                    print(f"{prefix}{Constant.chs2enkey(key)}: {value}")
                field_index+=1
            print("")


#   table:
#     - project: 项 目名, 
#       last_modify_user: 'buxk'
#       target_table: delta_checker.delta_table
#       target_filter: id > 100
#       source_table: delta_checker.full_table
#       source_filter: id > 100, 
#       transcode_fields: [id, name]
#       sync_strategy: replace
#       db_link: *clear_dblink
#       sync_switch: on
#       sys_status: 90
#       remark: 测试数据
#       sql: >
#         select * from delta_checker.full_table where id > 100

    
    # try:
    #     # 解析配置文件
    #     base_config, data_config_groups = parse_excel_config(file_path)
    #     print("基础配置:")
    #     for key, value in base_config.items():
    #         print(f"  {key}: {value}")

    #     print("\n数据配置分组:")
    #     for sheet_name, configs in data_config_groups.items():
    #         print(f"\n表 '{sheet_name}' 的配置:")
    #         for config in configs:
    #             print(
    #                 f"  序号: {config['序号']}, 项目名: {config['项目名']}, 目标表: {config['目标表']}, 策略: {config['同步策略']}"
    #             )

    #             # 示例：生成 SQL 语句
    #             if config['同步开关'] == '开启':
    #                 sql_statements = generate_sql_statements([config],
    #                                                          base_config)
    #                 if sql_statements:
    #                     print(f"    SQL 语句: {sql_statements[0]['SQL 语句']}")

    #     # 示例：为某个分组生成所有 SQL 语句
    #     if '数据配置' in data_config_groups:  # 假设存在名为 '数据配置' 的 sheet
    #         print("\n生成 '数据配置' 分组的所有 SQL 语句:")
    #         sql_statements = generate_sql_statements(
    #             data_config_groups['数据配置'], base_config)
    #         for stmt in sql_statements:
    #             print(f"  {stmt['项目名']} ({stmt['同步策略']}):")
    #             print(f"    {stmt['SQL 语句']}")

    # except Exception as e:
    #     print(f"错误: {e}")
